<script>
import ChatInput from "@/components/chat/ChatInput.vue";
import ChatMessageItem from "@/components/chat/ChatMessageItem.vue";
import FileUpload from "@/components/common/FileUpload.vue";
import ChatGroupSide from "@/components/chat/ChatGroupSide.vue";
import Emotion from "@/api/emotion";
import ChatRecord from "@/components/chat/ChatRecord.vue";
import ChatHistory from "@/components/chat/ChatHistory.vue";
import ChatAtBox from "@/components/chat/ChatAtBox.vue";
import GroupMemberSelector from "@/components/group/GroupMemberSelector.vue";
import RtcGroupJoin from "@/components/rtc/RtcGroupJoin.vue";
import HeadImage from "@/components/common/HeadImage.vue";
import {px2rem} from "@/utils/px2rem";
import {Dialog} from "vant";
import ImCamera from "@/api/camera";
import {CryptoUtil, toNotEncrypted} from "@/api/cryptoUtil";
import CameraDialog from "@/components/common/CameraDialog.vue";
import RtcPrivateVideo from "@/components/rtc/RtcPrivateVideo.vue";
import RtcGroupVideo from "@/components/rtc/RtcGroupVideo.vue";
import {bus} from "@/api/bus";

export default {
  name: "ChatConversation",
  components: {
    RtcGroupVideo,
    RtcPrivateVideo,
    CameraDialog,
    HeadImage,
    ChatInput,
    ChatMessageItem,
    FileUpload,
    ChatGroupSide,
    Emotion,
    ChatRecord,
    ChatHistory,
    ChatAtBox,
    GroupMemberSelector,
    RtcGroupJoin
  },
  data() {
    return {
      inputMessage: "",
      isKeyboardUp: false,
      showPopup: false,
      inputValue: "",
      isKeyboardVisible: false,
      // ChatBox migrate
      friend: {},
      group: {},
      groupMembers: [],
      sendImageUrl: "",
      sendImageFile: "",
      placeholder: "",
      isReceipt: true,
      showRecord: false,
      showSide: false,
      showHistory: false,
      lockMessage: false,
      showMinIdx: 0,
      reqQueue: [],
      isSending: false,
      camera: new ImCamera(),
      showCameraUtil: false,
      showPhoto: false,
      recordedBlobs: [],
      mediaRecorder: undefined,
      localStream: undefined,

      // message option menu
      showMessagePopover: false,
      // batch delete message list
      selectedMessages: [],
      selectAll: false,
      batchDeleteMode: false,
      // chat: null,
    }
  },
  methods: {
    async showHistoryBox() {
      await this.loadFriend(this.chat.targetId);
      this.showHistory = true;
    },
    closeHistoryBox() {
      this.showHistory = false;
    },
    // --------------------- top ChatBox
    closeCamera() {
      this.camera.close();
      this.showPhoto = false;
      this.showCameraUtil = false;
    },
    handlePhotoSelected(blob) {
      this.$refs.chatInputEditor.insertImage(blob);
    },
    handleVideoSelected(blob) {
      const element = this.$refs.chatInputEditor.insertVideo(blob);
      this.displayV(blob, element);
    },
    notifySend() {
      this.$refs.chatInputEditor.submit();
    },
    resetEditor() {
      this.$nextTick(() => {
        this.$refs.chatInputEditor.clear();
        this.$refs.chatInputEditor.focus();
      });
    },
    async sendMessage(fullList) {
      console.log('send message', fullList)
      this.resetEditor();
      this.readedMessage();
      // let sendText = this.isReceipt ? "【Receipt message】" : "";
      let sendText = this.isReceipt ? "" : "";
      let promiseList = [];
      for (let i = 0; i < fullList.length; i++) {
        let msg = fullList[i];

        switch (msg.type) {
          case "text":
            var content = sendText + msg.content;

            await this.sendTextMessage(content, msg.atUserIds);

            break;
          case "image":
            console.log('file', msg.content.file)

            await this.sendImageMessage(msg.content.file);
            break;
          case "file":

            await this.sendFileMessage(msg.content.file);
            break;
        }
      }
    },
    sendImageMessage(file) {
      return new Promise((resolve, reject) => {
        this.onImageBefore(file);

        var cryptoInstance = this.$store.getters.cryptoInstance();
        cryptoInstance.cryptoUtil.encryptFileReal(cryptoInstance, file).then(encryptFile=>{


          let formData = new FormData()
          formData.append('file', encryptFile)
          // this.$http.post("/image/upload", formData, {
          this.$http.post("/file/upload", formData, {
            headers: {
              'Content-Type': 'multipart/form-data'
            }
          }).then((data) => {
            console.log('onImageSuccess', data)
            this.onImageSuccess(data, file);
            resolve();
          }).catch((res) => {
            this.onImageFail(res, file);
            reject();
          })
          this.$nextTick(() => this.$refs.chatInputEditor.focus());
          this.scrollToBottom();
        });

      });
    },
    sendFileMessage(file) {
      return new Promise((resolve, reject) => {
        let check = this.$refs.fileUpload.beforeUpload(file);
        if (check) {
          this.$refs.fileUpload.onFileUpload({file});
        }
      })
    },
    displayV(videoFile, videoEl) {
      // Preconditions:
      if (!(videoFile instanceof Blob)) throw new Error('`videoFile` must be a Blob or File object.'); // The `File` prototype extends the `Blob` prototype, so `instanceof Blob` works for both.
      if (!(videoEl instanceof HTMLVideoElement)) throw new Error('`videoEl` must be a <video> element.');

      const newObjectUrl = URL.createObjectURL(videoFile);

      // URLs created by `URL.createObjectURL` always use the `blob:` URI scheme: https://w3c.github.io/FileAPI/#dfn-createObjectURL
      const oldObjectUrl = videoEl.currentSrc;
      if (oldObjectUrl && oldObjectUrl.startsWith('blob:')) {
        // It is very important to revoke the previous ObjectURL to prevent memory leaks. Un-set the `src` first.
        // See https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
        videoEl.src = ''; // <-- Un-set the src property *before* revoking the object URL.
        URL.revokeObjectURL(oldObjectUrl);
      }
      // Then set the new URL:
      videoEl.src = newObjectUrl;
      // And load it:
      videoEl.load(); // https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/load
    },
    handleCameraClose() {
    },
    openCamera() {
      this.camera.openVideo().then((stream) => {
        // this.localStream = stream;
        this.localStream = stream;
        this.showCameraUtil = true;
        this.$data.showPopup = false
        this.$nextTick(() => {
          this.$refs.cam.srcObject = stream;
          this.$refs.cam.muted = true;
          //   this.$refs.cam.play();
        })
        // resolve(stream);
      }).catch((e) => {
        this.$message.error("Failed to open camera")
        console.log("This camera failed to open:" + e.message)
        // reject(e);
      })
    },
    clickRecord() {
      this.$data.showRecord = true
      this.$data.showPopup = false
    },
    clickDocument() {
    },
    clickImage() {
    },
    clickShowPopup() {
      this.$data.showPopup = true
    },
    clickBack() {
      this.$store.commit('commonData/setIsShowChatConversation', false)
    },
    // call or video
    async showPrivateVideo(mode) {
      await this.loadFriend(this.chat.targetId);
      let rtcInfo = {
        mode: mode,
        isHost: true,
        friend: this.friend,
      }
      this.$eventBus.$emit("openPrivateVideo", rtcInfo);
      console.log('example(rtcInfo): ', JSON.stringify(rtcInfo))
      // current component
      // this.$refs.rtcPrivateVideoChat.open(rtcInfo);
    },
    clickVideo() {
      // video calling
      // this.$router.push('/chat-video')
      this.showPrivateVideo('video')
    },
    clickCall() {
      // voice calling
      // this.$router.push('/chat-call')
      this.showPrivateVideo('voice')
    },
    handleFocus() {
      this.isKeyboardUp = true;
      this.scrollToBottom();
    },
    handleBlur() {
      this.isKeyboardUp = false;
    },
    onScroll(e) {
      this.readedMessage()
      let scrollElement = e.target
      let scrollTop = scrollElement.scrollTop
      if (scrollTop < 30) {
        this.showMinIdx = this.showMinIdx > 20 ? this.showMinIdx - 20 : 0;
      }
    },
    scrollToBottom() {
      this.$nextTick(() => {
        let div = document.getElementById("chatScrollBox");
        div.scrollTop = div.scrollHeight;
      });

      this.$nextTick(() => {
        const chatContent = this.$refs.chatContent;
        console.log('chatContent.scrollHeight', chatContent.scrollHeight)
        if (chatContent) {
          chatContent.scrollTop = chatContent.scrollHeight;
        }
      });
    },
    px2rem,
    showName(msgInfo) {
      if (this.chat.type == 'GROUP') {
        let member = this.groupMembers.find((m) => m.userId == msgInfo.sendId);
        return member ? member.remarkNickName : "";
      } else {
        return msgInfo.sendId == this.mine.id ? this.mine.nickName : this.chat.showName
      }
    },
    headImage(msgInfo) {
      if (this.chat.type == 'GROUP') {
        let member = this.groupMembers.find((m) => m.userId == msgInfo.sendId);
        return member ? member.headImage : "";
      } else {
        return msgInfo.sendId == this.mine.id ? this.mine.headImageThumb : this.chat.headImage
      }
    },
    handleBatchDelete() {
      if (this.selectedMessages.length === 0) return;
      Dialog.confirm({
        title: 'Delete Message',
        message: `Are you sure you want to delete the selected ${this.selectedMessages.length} messages?`,
        confirmButtonColor: 'var(--chat-theme-color)',
        confirmButtonText: 'Confirm',
        cancelButtonText: 'Cancel',
      }).then(() => {
        const msgIdArr = this.selectedMessages.map(item => item.id);
        let url = `/message/${this.chat.type.toLowerCase()}/delete`
        this.$http({
          url: url,
          method: 'POST',
          data: {
            ids: msgIdArr,
          },
        }).then(() => {
          this.$store.commit("deleteMessages", this.selectedMessages);
          this.cancelBatchDelete();
        })
      });
    },
    cancelBatchDelete() {
      this.batchDeleteMode = false;
      this.selectedMessages = [];
      this.selectAll = false;
    },
    handleSelectAll(checked) {
      this.selectedMessages = checked ? [...this.chat.messages] : [];
    },
    enterBatchDeleteMode() {
      this.batchDeleteMode = true;
      this.selectedMessages = [];
    },
    // handle check box changes
    handleCheckChange(msgInfo, checked) {
      console.log('handle check change', msgInfo, checked)
      if (checked) {
        this.selectedMessages.push(msgInfo);
      } else {
        this.selectedMessages = this.selectedMessages.filter(m => m.id !== msgInfo.id);
      }
    },
    isMessageSelected(msgInfo) {
      return this.selectedMessages.some(m => m.id === msgInfo.id);
    },
    deleteMessage(msgInfo) {
      Dialog.confirm({
        title: 'Delete Message',
        message: 'Confirm delete message?',
        confirmButtonColor: 'var(--chat-theme-color)',
        confirmButtonText: 'Confirm',
        cancelButtonText: 'Cancel',
      }).then(() => {
        let url = `/message/${this.chat.type.toLowerCase()}/delete`
        this.$http({
          url: url,
          method: 'POST',
          data: {
            ids: [msgInfo.id],
          },
        }).then(() => {
          this.$store.commit("deleteMessage", msgInfo);
        })
      });
    },
    recallMessage(msgInfo) {
      Dialog.confirm({
        title: 'Recall Message',
        message: 'Confirm recall message?',
        confirmButtonColor: 'var(--chat-theme-color)',
        confirmButtonText: 'Confirm',
        cancelButtonText: 'Cancel',
      }).then(() => {
        let url = `/message/${this.chat.type.toLowerCase()}/recall`
        this.$http({
          url: url,
          method: 'POST',
          params: {
            id: msgInfo.id
          }
        }).then(() => {
          this.$message.success("the message is recalled");
          msgInfo = JSON.parse(JSON.stringify(msgInfo));
          msgInfo.type = 10;
          msgInfo.content = 'You retracted a message';
          msgInfo.status = this.$enums.MESSAGE_STATUS.RECALL;
          this.$store.commit("insertMessage", msgInfo);
        })
      });
    },
    onCall(type) {
      if (type == this.$enums.MESSAGE_TYPE.ACT_RT_VOICE) {
        this.showPrivateVideo('voice');
      } else if (type == this.$enums.MESSAGE_TYPE.ACT_RT_VIDEO) {
        this.showPrivateVideo('video');
      }
    },
    onSwitchReceipt() {
      this.isReceipt = !this.isReceipt;
      this.refreshPlaceHolder();
    },
    showEmotionBox() {
      let width = this.$refs.emotion.offsetWidth;
      let left = this.$elm.fixLeft(this.$refs.emotion);
      let top = this.$elm.fixTop(this.$refs.emotion);
      this.$refs.emoBox.open({
        x: left + width / 2,
        y: top
      })
    },
    onEmotion(emoText) {
      this.$refs.chatInputEditor.insertEmoji(emoText);
    },
    processReqQueue() {
      if (this.reqQueue.length && !this.isSending) {
        this.isSending = true;
        const reqData = this.reqQueue.shift();
        this.$http({
          url: this.messageAction,
          method: 'post',
          data: reqData.msgInfo
        }).then((res) => {
          reqData.resolve(res)
        }).catch((e) => {
          reqData.reject(e)
        }).finally(() => {
          this.isSending = false;
          this.processReqQueue();
        })
      }
    },
    clearInputValue() {
      this.$data.inputMessage = ''
    },
    sendTextMessage(sendText, atUserIds) {
      return new Promise((resolve, reject) => {
        if (!sendText.trim()) {
          reject();
        }
        let msgInfo = {
          content: sendText,
          type: 0
        }
        this.fillTargetId(msgInfo, this.chat.targetId);
        if (this.chat.type == "GROUP") {
          msgInfo.atUserIds = atUserIds;
          msgInfo.receipt = this.isReceipt;
        }
        this.lockMessage = true;
        this.sendMessageRequest(msgInfo).then((m) => {
          m.selfSend = true;
          console.log('insertMessage on then', m)
          m = toNotEncrypted(m, msgInfo.content)

          this.$store.commit("insertMessage", m);
          this.moveChatToTop();
          this.$nextTick(() => {

          })
        }).finally(() => {
          this.scrollToBottom();
          this.isReceipt = false;
          resolve();
        });
      });
    },
    moveChatToTop() {
      let chatIdx = this.$store.getters.findChatIdx(this.chat);
      this.$store.commit("moveTop", chatIdx);
    },
    closeRefBox() {
      this.$refs.emoBox.close();
      // this.$refs.atBox.close();
    },
    sendMessageRequest(msgInfo) {
      // console.log('sendMessageRequest', this.cryptoObj, msgInfo)
      // var cryptoUtil = this.cryptoObj.cryptoUtil
      // var keyObj = this.cryptoObj.keyObj
      // var sendCke = this.cryptoObj.sendCke
      // msgInfo.sendCke = sendCke

      var msgInfoCopy = JSON.parse(JSON.stringify(msgInfo))
      // msgInfoCopy.content = cryptoUtil.encode(keyObj, msgInfoCopy.content);
      // console.log('sendMessageRequest', this.cryptoObj, msgInfoCopy)

      return new Promise((resolve, reject) => {

        var cryptoInstance = this.$store.getters.cryptoInstance();
        var {encrypted, sendCke, code} = cryptoInstance.cryptoUtil.encryptText(cryptoInstance, msgInfoCopy.content);
        msgInfoCopy.content = encrypted;
        msgInfoCopy.sendCke = sendCke;
        msgInfoCopy.code = code;

        // Requests are queued to prevent "last-come-first-served" requests from causing message misordering
        this.reqQueue.push({msgInfo: msgInfoCopy, resolve, reject});
        this.processReqQueue();
      })
    },
    fillTargetId(msgInfo, targetId) {
      if (this.chat.type == "GROUP") {
        msgInfo.groupId = targetId;
      } else {
        msgInfo.recvId = targetId;
      }
    },
    readedMessage() {
      if (this.chat.unreadCount == 0) {
        return;
      }
      this.$store.commit("resetUnreadCount", this.chat)
      if (this.chat.type == "GROUP") {
        var url = `/message/group/readed?groupId=${this.chat.targetId}`
      } else {
        url = `/message/private/readed?friendId=${this.chat.targetId}`
      }
      this.$http({
        url: url,
        method: 'POST',
      }).then(() => {
      })
    },
    loadReaded(fId) {
      this.$http({
        url: "/message/private/maxReadedId",
        method: 'POST',
        params: {
          friendId: fId,
        }
      }).then((id) => {
        this.$store.commit("readedMessage", {
          friendId: fId,
          maxId: id
        });
      });
    },
    loadGroup(groupId) {
      this.$http({
        url: "/group/find",
        method: 'POST',
        params: {
          groupId: groupId
        }
      }).then((group) => {
        this.group = group;
        this.$store.commit("updateChatFromGroup", group);
        this.$store.commit("updateGroup", group);
      });

      this.$http({
        url: "/group/members",
        method: "POST",
        params: {
          groupId: groupId
        }
      }).then((groupMembers) => {
        this.groupMembers = groupMembers;
      });
    },
    // send Image
    onImageSuccess(data, file) {
      let msgInfo = JSON.parse(JSON.stringify(file.msgInfo));
      msgInfo.content = JSON.stringify(data);
      msgInfo.receipt = this.isReceipt;
      this.sendMessageRequest(msgInfo).then((m) => {
        msgInfo.loadStatus = 'ok';
        msgInfo.id = m.id;
        this.isReceipt = false;
        this.$data.showPopup = false
        this.$store.commit("insertMessage", msgInfo);
      })
    },
    onImageFail(e, file) {
      let msgInfo = JSON.parse(JSON.stringify(file.msgInfo));
      msgInfo.loadStatus = 'fail';
      this.$data.showPopup = false
      this.$store.commit("insertMessage", msgInfo);
    },
    generateId() {
      return String(new Date().getTime()) + String(Math.floor(Math.random() * 1000));
    },
    onImageBefore(file) {
      let url = URL.createObjectURL(file);
      let data = {
        originUrl: url,
        thumbUrl: url
      }
      let msgInfo = {
        id: 0,
        tmpId: this.generateId(),
        fileId: file.uid,
        sendId: this.mine.id,
        content: JSON.stringify(data),
        sendTime: new Date().getTime(),
        selfSend: true,
        type: 1,
        readedCount: 0,
        loadStatus: "loading",
        status: this.$enums.MESSAGE_STATUS.UNSEND
      }
      this.fillTargetId(msgInfo, this.chat.targetId);
      this.$store.commit("insertMessage", msgInfo);
      this.$data.showPopup = false
      this.moveChatToTop();
      this.scrollToBottom();
      // Save with the help of file object
      file.msgInfo = msgInfo;
    },
    onFileSuccess(url, file) {
      let data = {
        name: file.name,
        size: file.size,
        url: url
      }
      let msgInfo = JSON.parse(JSON.stringify(file.msgInfo));
      msgInfo.content = JSON.stringify(data);
      msgInfo.receipt = this.isReceipt
      this.sendMessageRequest(msgInfo).then((m) => {
        msgInfo.loadStatus = 'ok';
        msgInfo.id = m.id;
        this.isReceipt = false;
        this.refreshPlaceHolder();
        this.$store.commit("insertMessage", msgInfo);
        this.$data.showPopup = false
      })
    },
    onFileFail(e, file) {
      let msgInfo = JSON.parse(JSON.stringify(file.msgInfo));
      msgInfo.loadStatus = 'fail';
      this.$store.commit("insertMessage", msgInfo);
      this.$data.showPopup = false
    },
    onFileBefore(file) {
      let url = URL.createObjectURL(file);
      let data = {
        name: file.name,
        size: file.size,
        url: url
      }
      let msgInfo = {
        id: 0,
        tmpId: this.generateId(),
        sendId: this.mine.id,
        content: JSON.stringify(data),
        sendTime: new Date().getTime(),
        selfSend: true,
        type: 2,
        loadStatus: "loading",
        readedCount: 0,
        status: this.$enums.MESSAGE_STATUS.UNSEND
      }
      this.fillTargetId(msgInfo, this.chat.targetId);
      this.$store.commit("insertMessage", msgInfo);
      this.$data.showPopup = false
      this.moveChatToTop();
      this.scrollToBottom();
      file.msgInfo = msgInfo;
    },
    closeRecordBox() {
      this.showRecord = false;
    },
    onSendRecord(data) {
      let msgInfo = {
        content: JSON.stringify(data),
        type: 3,
        receipt: this.isReceipt
      }
      this.fillTargetId(msgInfo, this.chat.targetId);
      this.sendMessageRequest(msgInfo).then((m) => {
        m.selfSend = true;
        this.$store.commit("insertMessage", m);
        this.moveChatToTop();
        // this.$refs.chatInputEditor.focus();
        this.scrollToBottom();
        this.showRecord = false;
        this.isReceipt = false;
        this.refreshPlaceHolder();
      })
    },
    refreshPlaceHolder() {
      if (this.isReceipt) {
        this.placeholder = "【Receipt Message】"
      } else if (this.$refs.editBox && this.$refs.editBox.innerHTML) {
        this.placeholder = ""
      } else {
        this.placeholder = "Let's talk about something~";
      }
    },
    async loadFriend(friendId) {
      await this.$http({
        url: "/user/find",
        method: "POST",
        params: {
          id: friendId
        }
      }).then((friend) => {
        this.friend = friend;
        this.$store.commit("updateChatFromFriend", friend);
        this.$store.commit("updateFriend", friend);
      })
    },
    onGroupVideo() {
      // Invite members to start a call
      let ids = [this.mine.id];
      let maxChannel = this.$store.state.configStore.webrtc.maxChannel;
      this.$refs.rtcSel.open(maxChannel, ids, ids);
    },
    onInviteOk(members) {
      if (members.length < 2) {
        return;
      }
      let userInfos = [];
      members.forEach(m => {
        userInfos.push({
          id: m.userId,
          nickName: m.remarkNickName,
          headImage: m.headImage,
          isCamera: false,
          isMicroPhone: true
        })
      })
      let rtcInfo = {
        isHost: true,
        groupId: this.group.id,
        inviterId: this.mine.id,
        userInfos: userInfos
      }
      // this.$eventBus.$emit("openGroupVideo", rtcInfo);
      this.$refs.rtcGroupVideo.open(rtcInfo);
    },
  },
  computed: {
    navBarHeight() {
      return window.outerHeight
    },
    mine() {
      return this.$store.state.userStore.userInfo;
    },
    chat() {
      return this.$store.state.chatStore.activeChat;
    },
    title() {
      let title = this.chat.showName;
      if (this.chat.type == "GROUP") {
        let size = this.groupMembers.filter(m => !m.quit).length;
        title += `(${size})`;
      }
      return title;
    },
    messageAction() {
      return `/message/${this.chat.type.toLowerCase()}/send`;
    },
    unreadCount() {
      return this.chat.unreadCount;
    },
    messageSize() {
      if (!this.chat || !this.chat.messages) {
        return 0;
      }
      return this.chat.messages.length;
    }
  },
  watch: {
    messageSize: {
      handler(newSize, oldSize) {
        if (newSize > oldSize) {
          this.scrollToBottom();
        }
      }
    }
  },
  mounted() {
    // this.$data.chat = this.$store.state.chatStore.activeChat
    console.log('Chat Conversation1111111: ', this.chat)
    this.$nextTick(() => {
      this.scrollToBottom()
      this.readedMessage()
    })

    var code = Number(sessionStorage.getItem("code"));
    this.$store.dispatch("loadEncryption", code)
  }
}
</script>

<template>
  <div class="chat-conversation" v-if="chat">
    <div class="chat-header">
      <div class="title">
        <div class="back" @click="clickBack"><img src="../assets/image/all/back-btn-circle.png" alt=""></div>
        <div class="text">Message</div>
        <div class="more" title="Chat History" @click="showHistoryBox()"><img
            src="../assets/image/all/conversation-more-icon.png" alt=""></div>
      </div>
      <div class="user-container">
        <div class="avatar">
          <head-image :size="40" :name="title" :url="chat.headImage"></head-image>
        </div>
        <div class="user-message">{{ title }}</div>
        <div class="option-btn">
          <div class="camera" @click="clickVideo"><img src="../assets/image/all/video-icon-circle.png" alt="">
          </div>
          <div class="call" @click="clickCall"><img src="../assets/image/all/call-icon-circle.png" alt=""></div>
        </div>
      </div>
    </div>
    <div class="chat-content" ref="chatContent">
      <div v-show="batchDeleteMode" class="batch-action-bar">
        <div class="item-count">
          <el-checkbox v-model="selectAll" @change="handleSelectAll">Select All</el-checkbox>
          <span class="selected-count">Selected: {{ selectedMessages.length }} items</span>
        </div>
        <div class="btn-group">
          <el-button type="danger" size="mini" @click="handleBatchDelete">Confirm Delete</el-button>
          <el-button size="mini" @click="cancelBatchDelete">Cancel</el-button>
        </div>
      </div>
      <div class="im-chat-box" id="chatScrollBox" @scroll="onScroll" @click="readedMessage">
        <ul>
          <li v-for="(msgInfo, idx) in chat.messages" :key="idx" class="message-line">
            <chat-message-item v-if="idx >= showMinIdx" @call="onCall(msgInfo.type)"
                               :mine="msgInfo.sendId == mine.id" :headImage="headImage(msgInfo)"
                               :showName="showName(msgInfo)" :msgInfo="msgInfo"
                               :groupMembers="groupMembers"
                               :show-checkbox="batchDeleteMode"
                               :checked="isMessageSelected(msgInfo)"
                               @check-change="handleCheckChange(msgInfo, $event)"
                               @batch-delete="enterBatchDeleteMode"
                               @delete="deleteMessage"
                               @recall="recallMessage">
            </chat-message-item>
          </li>
        </ul>
      </div>
    </div>
    <div class="chat-input" :class="{ 'keyboard-up': isKeyboardUp }">
      <!--      <img class="custom-btn mr-5" src="../assets/image/all/record-icon.png" alt="">-->
      <ChatInput :ownerId="group.ownerId" class="custom-input" :group-members="groupMembers" ref="chatInputEditor"
                 @submit="sendMessage"/>
      <!--      <input ref="content" type="text" v-model="inputMessage" placeholder="Type a message..." @focus="handleFocus" @blur="handleBlur" />-->
      <div @click="clickShowPopup">
        <img class="custom-btn ml-5" src="../assets/image/all/add-btn.png" alt="">
      </div>
      <!--      <div class=" send-btn-container ml-5" @click="sendTextMessage(inputMessage)">-->
      <div class="send-btn-container ml-5" @click="notifySend()">
        <img class="custom-btn" src="../assets/image/all/send-btn.png" alt="">
      </div>
    </div>
    <van-popup v-model="showPopup" position="bottom" class="conversation-popup">
      <div class="chat-input-popup" :class="{ 'keyboard-up': isKeyboardUp }">
        <ChatInput :ownerId="group.ownerId" class="custom-input" :group-members="groupMembers" ref="chatInputEditor1"
                   @submit="sendMessage"/>
        <!--      <input-->
        <!--          ref="content"-->
        <!--          type="text"-->
        <!--          v-model="inputMessage"-->
        <!--          placeholder="Type a message..."-->
        <!--          @focus="handleFocus"-->
        <!--          @blur="handleBlur"-->
        <!--      />-->
        <div @click="clickShowPopup">
          <img class="custom-btn ml-5" src="../assets/image/all/add-btn.png" alt="">
        </div>
        <!--      <div class=" send-btn-container ml-5" @click="sendTextMessage(inputMessage)">-->
        <div class=" send-btn-container ml-5" @click="notifySend()">
          <img class="custom-btn" src="../assets/image/all/send-btn.png" alt="">
        </div>
      </div>
      <div class="popup-content">
        <div class="row-center">
          <!--  Camera Features   -->
          <!--
                    <file-upload :action="'/image/upload'" :maxSize="5 * 1024 * 1024"
                                 :fileTypes="['image/jpeg', 'image/png', 'image/jpg', 'image/webp', 'image/gif']"
                                 @before="onImageBefore" @success="onImageSuccess" @fail="onImageFail">
                      <div class="icon-btn" @click="clickCamera">
                        <img class="flex-center" src="../assets/image/all/camera-text-color.png" alt="">
                      </div>
                    </file-upload>    -->
          <div class="icon-btn" @click="openCamera">
            <img class="" src="../assets/image/all/camera-text-color.png" alt="">
          </div>
          <div class="icon-btn" @click="clickRecord">
            <img class="" src="../assets/image/all/record-text-color.png" alt="">
          </div>
          <file-upload ref="fileUpload" :action="'/file/upload'" :maxSize="10 * 1024 * 1024"
                       @before="onFileBefore" @success="onFileSuccess" @fail="onFileFail">
            <div class="icon-btn" @click="clickDocument">
              <img class="" src="../assets/image/all/doc-text-color.png" alt="">
            </div>
          </file-upload>
        </div>
        <div class="row-center">
          <file-upload :action="'/image/upload'" :maxSize="5 * 1024 * 1024"
                       :fileTypes="['image/jpeg', 'image/png', 'image/jpg', 'image/webp', 'image/gif']"
                       @before="onImageBefore" @success="onImageSuccess" @fail="onImageFail">
            <div class="icon-btn" @click="clickImage">
              <img class="" src="../assets/image/all/gallery-text-color.png" alt="">
            </div>
          </file-upload>
          <div class="icon-btn"></div>
          <div class="icon-btn"></div>
        </div>
      </div>
    </van-popup>
    <!--    <emotion ref="emoBox" @emotion="onEmotion"></Emotion>-->
    <chat-record :visible="showRecord" @close="closeRecordBox" @send="onSendRecord"></chat-record>
    <group-member-selector ref="rtcSel" :groupId="group.id" @complete="onInviteOk"></group-member-selector>
    <rtc-group-join ref="rtcJoin" :groupId="group.id"></rtc-group-join>
    <chat-history :visible="showHistory" :chat="chat" :friend="friend" :group="group"
                  :groupMembers="groupMembers" @close="closeHistoryBox"></chat-history>
    <camera-dialog :visible.sync="showCameraUtil"
                   @photo-selected="handlePhotoSelected"
                   @video-selected="handleVideoSelected"
                   @close="handleCameraClose"
    />
    <!--    <rtc-private-video ref="rtcPrivateVideoChat"></rtc-private-video>-->
    <!--    <rtc-group-video ref="rtcGroupVideoChat"></rtc-group-video>-->
  </div>
</template>

<style scoped lang="scss">
// --------------new
::v-deep .el-dialog__body, ::v-deep .el-dialog__header {
  padding: 0 !important;
}

.rtc-private-video-dialog {
  background: rgba(0, 0, 0, .5);
  padding: 0 !important;
  width: 100%;
  height: 100vh;
}

// camera styles
.chat-camera-container {
  position: relative;
  width: 100vw;
  height: 100vh;
  background-image: url('../assets/image/all/camera-bg.png');
  background-size: 100% 100%;
  //background-position: center center;
  background-repeat: no-repeat;
  display: flex;
  flex-direction: column;

  video, canvas {
    //position: absolute;
    //top: 0;
    //left: 0;
    //margin-top: 0;
    //width: 100vw;
    //height: 100vh;
    //z-index: 0;
  }

  .title {
    z-index: 999;
    display: flex;
    justify-content: space-between;
    align-items: center;
    height: 50px;
    padding: 50px 20px 10px;

    .text {
      font-size: 22px;
      color: var(--im-color-white);
    }

    .back, .more {
      background: rgba(255, 255, 255, 0.1);
      box-shadow: 0 4px 12px rgba(13, 10, 44, 0.06);
    }

    .custom-btn-camera {
      background: rgba(255, 255, 255, 0.1);
      box-shadow: 0 4px 12px rgba(13, 10, 44, 0.06);
      width: 45px;
      height: 45px;
      border-radius: 50%;
    }
  }

  .content {
    z-index: 0;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
  }

  .option {
    z-index: 999;
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translate(-50%, 0);
    height: 100px;
    display: flex;
    justify-content: space-around;
    align-items: center;
  }
}

// ----
.more {
  width: 42px;
  height: 42px;
  display: flex;
  justify-content: center;
  align-items: center;
  img {
    width: 100%;
    height: 100%;
  }
}
.back, .camera, .call {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  background: rgba(255, 255, 255, 0.1);
  box-shadow: 0 4px 12px rgba(13, 10, 44, 0.06);

  img {
    width: 22px;
    //height: 22px;
  }
}

.im-chat-box {
  > ul {
    padding: 0 30px;

    li {
      list-style-type: none;
    }

    .chat-msg-check {
      position: absolute;
    }
  }
}

.conversation-popup {
  height: 260px;

  .chat-input-popup {
    position: fixed;
    bottom: 260px;
    left: 0;
    right: 0;
    height: 50px;
    background: white;
    display: flex;
    align-items: center;
    padding: 5px 10px;
    box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.1);

    .custom-btn {
      background: rgba(255, 255, 255, 0.1);
      box-shadow: 0 4px 12px rgba(13, 10, 44, 0.06);
      width: 32px;
      height: 32px;
      border-radius: 50%;
    }

    .send-btn-container {
      width: 32px;
      height: 32px;
    }

    input, .custom-input {
      flex: 1;
      border: none;
      outline: none;
      padding: 8px;
      border-radius: 5px;
      background: #f0f0f0;
    }

    button:active {
      opacity: 0.7;
    }
  }

  .popup-content {
    height: 100%;
    padding: 10px 12px;
    display: flex;
    justify-content: center;
    flex-direction: column;
    gap: 10px;

    .row-center {
      flex: 1;
      display: flex;
      justify-content: space-around;
      align-items: center;

      .icon-btn {
        width: 80px;
        height: 80px;

        img {
          width: 80px;
          height: 68px;
        }
      }
    }
  }
}

.chat-conversation {
  background: #f0f0f3;
  background: #fff;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100vh;

  .chat-header, .chat-input {
    //flex-shrink: 0;
    //position: fixed;
    //left: 0;
    //z-index: 1;
    width: 100%;
  }

  .chat-header {
    //top: 0;
    height: 120px;
    background: var(--im-color-white);
    color: white;
    display: flex;
    padding: 5px 10px 0 10px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
    z-index: 100;
    flex-direction: column;

    .title {
      display: flex;
      justify-content: space-between;
      align-items: center;
      height: 50px;

      .text {
        font-size: 22px;
        color: var(--chat-name-text-color);
      }
    }

    .user-container {
      display: flex;
      justify-content: space-between;
      align-items: center;
      height: 60px;
      padding: 0 12px;

      .avatar {
        width: 40px;
        height: 40px;
        border-radius: 50%;
        background: var(--slot-color);
      }

      .user-message {
        flex: 1;
        margin-left: 20px;
        text-align: left;
        font-size: 20px;
        color: var(--chat-name-text-color);
      }

      .option-btn {
        display: flex;

        .camera, .call {
          background: rgba(255, 255, 255, 0.1);
          box-shadow: 0 4px 12px rgba(13, 10, 44, 0.06);
          width: 42px;
          height: 42px;
          border-radius: 50%;
        }
      }
    }
  }

  .chat-content {
    //height: 200px;
    //height: 600px;
    flex: 1;
    //height: calc(100vh - 170px);
    //flex-grow: 1;
    overflow-y: auto;
    //padding-top: 120px;
    padding-bottom: 140px;
  }

  .chat-message {
    display: flex;
    margin-bottom: 10px;
  }

  .chat-message.other {
    justify-content: flex-start;
  }

  .chat-message.mine {
    justify-content: flex-end;
  }

  .bubble {
    max-width: 70%;
    padding: 8px 12px;
    border-radius: 15px;
    font-size: 14px;
    line-height: 1.5;
    word-wrap: break-word;
  }

  .chat-message.other .bubble {
    background: #fff;
    border: 1px solid #ddd;
  }

  .chat-message.mine .bubble {
    background: #007bff;
    color: white;
  }

  .chat-input {
    //bottom: 0;
    height: 50px;
    background: white;
    display: flex;
    align-items: center;
    padding: 5px 10px;
    box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.1);
    position: fixed;
    right: 0;
    bottom: 0;
    z-index: 999;

    .custom-btn {
      background: rgba(255, 255, 255, 0.1);
      box-shadow: 0 4px 12px rgba(13, 10, 44, 0.06);
      width: 32px;
      height: 32px;
      border-radius: 50%;
    }

    .send-btn-container {
      width: 32px;
      height: 32px;
    }
  }

  .chat-input input, .chat-input .custom-input {
    flex: 1;
    border: none;
    outline: none;
    padding: 8px;
    border-radius: 5px;
    background: #f0f0f0;
  }

  .chat-input button {
    margin-left: 10px;
    padding: 8px 12px;
    background: #007bff;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
  }

  .chat-input button:active {
    opacity: 0.7;
  }

  .keyboard-up {
    transform: translateY(-100px);
    transition: transform 0.1s;
  }
}

.batch-action-bar {
  position: sticky;
  top: 0;
  z-index: 10;
  width: auto;
  padding: 10px 5px;
  background: #f5f7fa;
  border-bottom: 1px solid #ebeef5;
  display: flex;
  gap: 15px;
  flex-direction: column;
  justify-content: flex-start;

  .item-count {
    display: flex;
  }

  .btn-group {
    display: flex;
    justify-content: flex-end;
  }

  .selected-count {
    color: #606266;
    margin-left: auto;
  }
}
</style>